Skip to content

Implement HEALPix grids#910

Open
davidhassell wants to merge 84 commits intoNCAS-CMS:mainfrom
davidhassell:healpix
Open

Implement HEALPix grids#910
davidhassell wants to merge 84 commits intoNCAS-CMS:mainfrom
davidhassell:healpix

Conversation

@davidhassell
Copy link
Collaborator

Fixes #909

Requires NCAS-CMS/cfdm#371

@davidhassell davidhassell marked this pull request as draft November 27, 2025 17:03
@davidhassell davidhassell added this to the NEXTVERSION milestone Feb 18, 2026
@davidhassell davidhassell added regridding Relating to regridding operations enhancement New feature or request labels Feb 18, 2026
@davidhassell davidhassell marked this pull request as ready for review February 19, 2026 15:28
@davidhassell davidhassell added the UGRID Relating to UGRID mesh topologies label Mar 11, 2026
Copy link
Member

@sadielbartholomew sadielbartholomew left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hit 'enter' accidentally mid-review, please ignore this until I have finished the review with a second submission! Sorry.

Overall looks decent! But I have some more considerable concerns (plus minor comments, see in-line):

  1. There is the potential for module shadowing on healpix here - namely, because we have a module named healpix.py, import healpix could pick up on that instead of the external healpix library as intended (in certain cases, e.g. if whatever logic/application is running from the cf directory as CWD), which could lead to hard to diagnose issues somewhere down the line including unintended name clashes (probably mostly for us rather than the user but that's still bad).

    For example, when reviewing I was in the cf directory to explore and would run into the following:

    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/home/slb93/git-repos/cf-python/cf/field.py", line 5393, in healpix_increase_refinement_level
        or refinement_level > healpix_max_refinement_level()
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/home/slb93/git-repos/cf-python/cf/functions.py", line 3480, in healpix_max_refinement_level
        return healpix.nside2order(healpix._chp.NSIDE_MAX)
               ^^^^^^^^^^^^^^^^^^^
    AttributeError: module 'healpix' has no attribute 'nside2order'

    I suggest we rename the module to be safe. How about calling it healpix_utils, e.g. to mirror the existing dask_utils?

  2. As indicated in a few illustrative in-line comments there, across the cf/data/dask_utils_healpix.py module you use examples which specify the functions in question being called via cf.data.dask_utils.<function>, but none of those are exposed via that module and cf.data.dask_utils_healpix doesn't get exposed either. I am wondering therefore if you meant to include the module or them individually in an appropriate __init.py__? (Or maybe you moved them out from dask_utils and forgot to update something there?)

named `ESMF` with the old module name also being accepted for import,
version 8.7.0 or newer. This is easily installed via conda with
* `esmpy <https://earthsystemmodeling.org/esmpy/>`_, version 8.7.0 or
newer. This is easily installed via conda with
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not that this originates from this PR, but since we're touching it here: one should always avoid using terms like 'easy', 'simple' and similar because they are subjective and can put off users/readers if they don't find it easy as promised. I suggest just:

Suggested change
newer. This is easily installed via conda with
newer. This can be installed via conda with

Comment on lines +302 to +307
* `healpix <https://pypi.org/project/healpix>`_, version 2025.1 or
newer. This package is not required to read and write HEALPix
datasets, but may be needed for particular manipulations with
HEALPix grids, such as creating latitude and longitude coordinates,
regridding, some changes to the refinement level, and some
collapses.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm... I am not 100% comfortable/happy with such a vague requisite. For one, it isn't then clear what tests would be expected to fail and therefore be skipped if healpix isn't available. Surely we can be more specific - or are there particular reasons we can't be I haven't picked up on?

Comment on lines +1373 to +1374
Define how to coarsening neighbourhood for each
axis. A dictionary key is an integer axis position,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There appears to be a missing word or (likely) set of words here, perhaps something like this was intended(?):

Suggested change
Define how to coarsening neighbourhood for each
axis. A dictionary key is an integer axis position,
Define how large to set the coarsening neighbourhood for
each axis. A dictionary key is an integer axis position,

ndim = self.ndim
for k in axes:
if k < -ndim or k > ndim:
raise ValueError("axis {k} is out of bounds for {ndim}-d data")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing the f-string prefix, plus a capital ideally for a bit more polish:

Suggested change
raise ValueError("axis {k} is out of bounds for {ndim}-d data")
raise ValueError(f"Axis {k} is out of bounds for {ndim}-d data")

# `None` then there are no vertical coordinates.
z_index: Any = None
# The original field/domain before any transformations are applied
# (such as creating lat/lon coordinates, or converting to from
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# (such as creating lat/lon coordinates, or converting to from
# (such as creating lat/lon coordinates, or converting from

(Or to/from?)

f"Can't change HEALPix indexing scheme of {f!r}: "
"indexing_scheme in the healpix grid mapping coordinate "
"reference must be one of "
f"{healpix_indexing_schemes()!r}. Got {new_indexing_scheme!r}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
f"{healpix_indexing_schemes()!r}. Got {new_indexing_scheme!r}"
f"{healpix_indexing_schemes()!r}. Got {indexing_scheme!r}"


# Get the lat/lon coordinates
x_key, x = f.auxiliary_coordinate(
"Y",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"Y",
"X",

default=(None, None),
)
y_key, y = f.auxiliary_coordinate(
"X",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"X",
"Y",

bounds that lie exactly on the north or south pole. If
`None` (the default) then the longitudes of such
points are determined by whichever algorithm was used
to create the coordinates, which will could result in
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
to create the coordinates, which will could result in
to create the coordinates, which could result in

including `numpy` and `Data` objects. The units of the
radius are assumed to be metres, unless specified by a
`Data` object. If the special value ``'earth'`` is
given then the default radius taken as 6371229
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
given then the default radius taken as 6371229
given then the default radius is taken as 6371229

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request regridding Relating to regridding operations UGRID Relating to UGRID mesh topologies

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement HEALPix grids

2 participants